package org.as3search.providers.impl {
	/*
	 * as3search - http://code.google.com/p/as3search
	 * Copyright (c) 2009-2010 by respective authors. All rights reserved.
	 *
	 * This library is free software; you can redistribute it and/or modify it under the
	 * terms of the GNU Lesser General Public License as published by the Free Software
	 * Foundation; either version 2.1 of the License, or (at your option) any later
	 * version.
	 *
	 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
	 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
	 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
	 *
	 * You should have received a copy of the GNU Lesser General Public License along
	 * with this library; if not, write to the Free Software Foundation, Inc.,
	 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
	 */
	
	import flash.errors.IllegalOperationError;
	import flash.utils.getQualifiedClassName;
	import org.as3search.providers.SearchProvider;
	import org.as3search.providers.SearchProviderMapping;

	/**
	 * <code>SearchProviderMappingImpl</code> is the default implementation
	 * of <code>SearchProviderMapping</code> used by as3search.
	 * 
	 * @see org.as3search.providers.SearchProviderMapping
	 */
	public class SearchProviderMappingImpl implements SearchProviderMapping {
		
		private var _targetType:Class;
		
		private var _providerType:Class;
		/**
		 * Creates a new <code>SearchProviderMappingImpl</code> instance.
		 * @param	targetType		The target type that this <code>providerType</code> will be mapped to.
		 * @param	providerType	The provider type that is mapped to <code>targetType</code>
		 */
		public function SearchProviderMappingImpl(targetType:Class, providerType:Class) {
			if (targetType == null)
				throw new ArgumentError("'targetType' cannot be null!");
			if (providerType == null)
				throw new ArgumentError("'providerType' cannot be null!");
			
			_targetType = targetType;
			
			try {
				var providerTest:Object = new providerType();
				if (!(providerTest is SearchProvider)) {
					throw new ArgumentError("'" + getQualifiedClassName(providerType).replace("::",".") + "' " +
						"does not implement org.as3search.providers.SearchProvider");
				} else {
					_providerType = providerType;
				}
			} catch (e:ArgumentError) {
				throw new ArgumentError("Could not instantiate '" + getQualifiedClassName(providerType).replace("::",".") +
					"'. Implementors of org.as3search.providers.SearchProvider must define " +
					"a constructor that does not require arguments.");
			}
		}
		/**
		 * @inheritDoc
		 */
		public function create(value:Object):SearchProvider {
			if (providerType == null)
				throw new IllegalOperationError("'providerType' was not set by constructor. Unable to create " +
					"new SearchProvider.");
			
			var returnee:SearchProvider = new providerType();
			try {
				returnee.target = value;
			} catch (e:ArgumentError) {
				throw new ArgumentError("The newly created provider did not accept an object of type " +
					"'" + getQualifiedClassName(value).replace("::",".") + "' as its target.");
			}
				
			return returnee;
		}
		/**
		 * @inheritDoc
		 */
		public function get targetType():Class { return _targetType; }
		/**
		 * @inheritDoc
		 */
		public function get providerType():Class { return _providerType; }
	}
}